http = require 'http'
fs = require 'fs'
path = require 'path'
mime = require 'mime'
cache = {}

config = require './config/web'
server = null

send404 = (response)->
  response.writeHead 404, {'Content-Type': 'text/plain'}
  response.end 'Error 404: resource not found.'

sendFile = (response, filePath, fileContents) ->
  response.writeHead 200, {"Content-type": mime.lookup(path.basename filePath)}
#  console.log "response file with content " + fileContents
#  debugger
  response.end fileContents

serveStatic = (response, cache, absPath)->
  if(cache[absPath])
    console.log "File %s exist in cache , use cache serve. ", absPath
    sendFile(response, absPath, cache[absPath])
    return

  fs.exists absPath, (exists)->
    unless exists
      console.log "File %s does not exist, send 404", absPath
      send404 response
      return

    fs.readFile absPath, (err, data)->
      if err
        console.log "Read file %s error, err= %s, send 404", absPath, err
        send404(response)
      else
        cache[absPath] = data
        console.log "File %s is not cached, cached it and response.", absPath
        sendFile(response, absPath, data)

exports.start = ->
  server = http.createServer (request, response)->
    normalizedPath =  path.join config.webroot, if request.url == '/' then config.welcomeFile else request.url

    console.log "Access file #{normalizedPath}..."

    serveStatic(response, cache, normalizedPath)

  server.listen 3000, ()-> console.log "Server listening on port 3000 at " + new Date() + "."

  watcher = require 'chokidar'

  # watch static resource
  staticWatcher = watcher.watch config.webroot, {ignored: /^(?:[\/\\]\.)|(?:.*\.(?:map)|(?:coffee(?:___jb_(bak|old)___)?))$/, persistent: true}
  staticWatcher.on 'change', (filePath)->
    normalizedPath = path.normalize filePath
    fs.readFile normalizedPath, (err, data)->
      if err
        console.log "Read file %s error, err= %s when update cache..", normalizedPath, err
        return
      cache[normalizedPath] = data
      console.log "File #{normalizedPath} has been changed, cache refreshed."

  chatServer = require './lib/chat_server'
  chatServer.listen(server)

exports.stop = ->
  server.close(->
    console.log "server at localhost port 3000 closed."
  ,) if server
  server = null

